package com.zx.crowdfunding.handler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.zx.crowdfunding.api.MySQLRemoteService;
import com.zx.crowdfunding.config.OSSProperties;
import com.zx.crowdfunding.constant.CrowdFundingConstant;
import com.zx.crowdfunding.entity.vo.DetailProjectVO;
import com.zx.crowdfunding.entity.vo.MemberConfirmInfoVO;
import com.zx.crowdfunding.entity.vo.MemberLoginVO;
import com.zx.crowdfunding.entity.vo.ProjectVO;
import com.zx.crowdfunding.entity.vo.ReturnVO;
import com.zx.crowdfunding.util.CrowdFundingUtil;
import com.zx.crowdfunding.util.ResultEntity;

/**
 * 项目 - Handler
 * @author 郑雪
 * @date 2022-01-02
 */
@Controller
public class ProjectConsumerHandler {
	
	/**
	 * 第三方OSS对象存储服务接口属性
	 */
	@Autowired
	private OSSProperties ossProperties;
	
	/**
	 * MySQL数据服务远程接口
	 */
	@Autowired
	private MySQLRemoteService mysqlRemoteService;
	
	/**
	 * 获取项目详情
	 * @param projectId 项目id
	 * @return 跳转到项目详情页面
	 */
	@RequestMapping("/get/project/detail/{projectId}")
	public String getProjectDetail(@PathVariable("projectId") Integer projectId, ModelMap modelMap) {
		
		// 调用远程接口查询项目详情
		ResultEntity<DetailProjectVO> resultEntity = mysqlRemoteService.getProjectDetailRemote(projectId);
		
		// 检查查询结果
		String result = resultEntity.getResult();
		
		// 如果成功
		if(ResultEntity.SUCCESS.equals(result)) {
			
			// 获取查询到的数据
			DetailProjectVO detailProjectVO = resultEntity.getData();
			
			// 将数据存入模型
			modelMap.addAttribute(CrowdFundingConstant.ATTR_NAME_DETAIL_PROJECT, detailProjectVO);
			
		}
		
		// 跳转到项目详情页面
		return "project-detail";
	}
	
	/**
	 * 创建项目第三步，保存确认信息，将ProjectVO存入数据库中
	 * @param memberConfirmInfoVO 发起人确认信息视图对象
	 * @param session 当前会话
	 * @return 重定向到创建项目第四步，完成页面
	 */
	@RequestMapping("/create/confirm")
	public String saveConfirm(MemberConfirmInfoVO memberConfirmInfoVO, HttpSession session, ModelMap modelMap) {
		
		// 1.从Session域中获取之前缓存的ProjectVO对象
		ProjectVO templeProjectVO = (ProjectVO) session.getAttribute(CrowdFundingConstant.ATTR_NAME_TEMPLE_PROJECT);
		
		// 2.判断ProjectVO对象是否为空
		if(templeProjectVO == null) {
			throw new RuntimeException(CrowdFundingConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
		}
		
		// 3.将确认信息数据设置到ProjectVO对象中
		templeProjectVO.setMemberConfirmInfoVO(memberConfirmInfoVO);
		
		// 4.从Session个域中获取当前会员登录VO对象
		MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute(CrowdFundingConstant.ATTR_NAME_LOGIN_MEMBER);
		
		// 5.当前登录的会员id
		Integer memberId = memberLoginVO.getId();
		
		// 6.调用远程接口添加项目
		ResultEntity<String> saveResultEntity = mysqlRemoteService.saveProjectVORemote(templeProjectVO, memberId);
		
		// 7.如果失败
		if(ResultEntity.FAILED.equals(saveResultEntity.getResult())) {
			
			modelMap.addAttribute(CrowdFundingConstant.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());
			
			return "project-confirm";
		}
		
		// 8.将临时的ProjectVO对象从Session域中删除
		session.removeAttribute(CrowdFundingConstant.ATTR_NAME_TEMPLE_PROJECT);

		// 9.重定向到完成页面
		return "redirect:/project/to/create/success/page";
	}
	
	/**
	 * 创建项目第二步，添加回报信息到Session域中
	 * @param returnVO 回报视图对象
	 * @param session 当前会话
	 * @return JSON数据
	 */
	@RequestMapping("/create/save/return.json")
	@ResponseBody
	public ResultEntity<String> saveReturn(ReturnVO returnVO, HttpSession session){
		
		try {
			// 1.从Session域中获取之前缓存的ProjectVO对象
			ProjectVO templeProjectVO = (ProjectVO) session.getAttribute(CrowdFundingConstant.ATTR_NAME_TEMPLE_PROJECT);
			
			// 2.判断ProjectVO对象是否为空
			if(templeProjectVO == null) {
				
				// 返回失败
				return ResultEntity.failed(CrowdFundingConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
			}
			
			// 3.从ProjectVO对象中获取存储回报信息的集合
			List<ReturnVO> returnVOList = templeProjectVO.getReturnVOList();
			
			// 4.判断回报信息集合是否为空
			if(returnVOList == null) {
				
				// 5.创建集合对象对returnVOList进行初始化
				returnVOList = new ArrayList<ReturnVO>();
				
				// 6.为了让以后能够正常使用这个集合，设置到ProjectVO对象中
				templeProjectVO.setReturnVOList(returnVOList);
			}
			
			// 7.将收集了表单数据的ReturnVO对象存入集合中
			returnVOList.add(returnVO);
			
			// 8.把数据有变化的ProjectVO对象重新存入Session域中，以确保新的数据最终能够存入Redis
			session.setAttribute(CrowdFundingConstant.ATTR_NAME_TEMPLE_PROJECT, templeProjectVO);
		
			// 9.返回成功
			return ResultEntity.successWithoutData();
			
		} catch (Exception e) {
			e.printStackTrace();
			
			// 返回失败
			return ResultEntity.failed(e.getMessage());
		}
		
	}
	
	/**
	 * 上传回报图片
	 * @param returnPicture 上传文件（回报图片）
	 * @return JSON数据
	 * @throws IOException 
	 */
	@RequestMapping("/create/upload/return/picture.json")
	@ResponseBody
	public ResultEntity<String> uploadReturnPicture(MultipartFile returnPicture) throws IOException {
		
		// 上传文件到OSS服务器（调用第三方OSS接口）
		ResultEntity<String> uploadReturnPictureResultEntity = CrowdFundingUtil.uploadFileToOss(
				ossProperties.getEndPoint(), 
				ossProperties.getBucketName(), 
				ossProperties.getBucketDomain(), 
				ossProperties.getAccessKeyId(), 
				ossProperties.getAccessKeySecret(), 
				returnPicture.getInputStream(), 
				returnPicture.getOriginalFilename());
		
		// 返回上传文件的结果
		return uploadReturnPictureResultEntity;
	}

	/**
	 * 创建项目第一步，保存项目及发起人信息到Session域中
	 * @param projectVO 项目视图对象
	 * @param headerPicture 上传文件（项目头图）
	 * @param detailPictureList 上传文件（项目详情图片）
	 * @param session 当前会话
	 * @return 重定向到创建项目第二步，回报设置页面
	 * @throws IOException 
	 */
	@RequestMapping("/create/project/information")
	public String createProjectInformation(
				ProjectVO projectVO, 
				MultipartFile headerPicture, 
				List<MultipartFile> detailPictureList, 
				HttpSession session, 
				ModelMap modelMap
			) throws IOException {
		
		// 1.上传项目头图
		boolean headerPictureIsEmpty = headerPicture.isEmpty();
		if(!headerPictureIsEmpty) {
			
			// 2.上传文件到OSS服务器（调用第三方OSS接口）
			ResultEntity<String> uploadHeaderPictureResultEntity = CrowdFundingUtil.uploadFileToOss(
					ossProperties.getEndPoint(), 
					ossProperties.getBucketName(), 
					ossProperties.getBucketDomain(), 
					ossProperties.getAccessKeyId(), 
					ossProperties.getAccessKeySecret(), 
					headerPicture.getInputStream(), 
					headerPicture.getOriginalFilename());
			
			String result = uploadHeaderPictureResultEntity.getResult();
			
			// 3.判断项目头图是否上传成功
			if(ResultEntity.SUCCESS.equals(result)) {
				
				// 4.从返回数据中获取图片访问路径
				String headerPicturePath = uploadHeaderPictureResultEntity.getData();
				
				// 5.存入ProjectVO对象中
				projectVO.setHeaderPicturePath(headerPicturePath);
			} else {
				
				// 如果失败
				modelMap.addAttribute(CrowdFundingConstant.ATTR_NAME_MESSAGE, CrowdFundingConstant.MESSAGE_HEADER_PIC_UPLOAD_FAILED);
				return "project-launch";
			}
		}
		
		// 创建一个用来存放详情图片路径的集合
		List<String> detailPicturePathList = new ArrayList<String>();
		
		// 4.遍历项目详情图片集合
		for (MultipartFile detailPicture : detailPictureList) {
			
			// 5.判断当前detailPicture是否为空
			if(!detailPicture.isEmpty()) {
				
				// 6.上传文件到OSS服务器（调用第三方OSS接口）
				ResultEntity<String> uploadDetailPictureResultEntity = CrowdFundingUtil.uploadFileToOss(
						ossProperties.getEndPoint(), 
						ossProperties.getBucketName(), 
						ossProperties.getBucketDomain(), 
						ossProperties.getAccessKeyId(), 
						ossProperties.getAccessKeySecret(), 
						detailPicture.getInputStream(), 
						detailPicture.getOriginalFilename());
				
				String result = uploadDetailPictureResultEntity.getResult();
				
				// 7.判断项目详情图片是否上传成功
				if(ResultEntity.SUCCESS.equals(result)) {
					
					// 8.从返回数据中获取图片访问路径
					String detailPicturePath = uploadDetailPictureResultEntity.getData();
					
					// 9.放入集合中
					detailPicturePathList.add(detailPicturePath);
					
				}
				
			}
		}
		
		// 10.将存放详情图片路径的集合存入ProjectVO对象中
		projectVO.setDetailPicturePathList(detailPicturePathList);
		
		// 11.将ProjectVO对象存入Session域中
		session.setAttribute(CrowdFundingConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);
		
		// 12.重定向到创建项目第二步，回报设置页面
		return "redirect:/project/to/return/info/page";
	}
	
}
